package com.cskaoyan.javase.oop3._2inner._4anonymous._0introduction;

/**
 * 匿名内部类
 * 我们之前讲解的成员内部类,静态内部类,局部内部类
 * 都属于使用特定语法在一个类当中定义了一个类,在使用它们时,还需要创建它们的对象
 * 所以接下来讲解的匿名内部类就直接省略了定义类的过程,直接使用语法创建内部类对象
 * 所以匿名内部类,更准确的叫法是匿名内部类对象.(它的语法是创建了一个对象,而不是定义类)
 *
 * 匿名内部类属于特殊的局部内部类,是一个匿名的,没有名字的局部内部类
 * 当然它没有名字,语法也很特殊,它的语法是直接创建对象
 * 语法:
 * new 类名/接口名(){
 *    // 类名/接口名的子类类体
 * };
 * 解释:
 *      1.new关键字仍然表示创建对象
 *      2.类名/接口名 可以是普通类名,也可以是抽象类类名,也可以写接口名
 *      3.匿名内部类的语法中隐含了继承(extends)或者实现(implements)
 *          表示创建语法结构中"类名/接口名"的子类对象
 *      4.匿名内部类实际上是创建了一个对象,是"类名/接口名"的子类对象
 *      5.语法结构中的大括号是"类名/接口名"的子类类体
 *      6.以下语法结构实际上就是一个匿名子类
 *      类名/接口名(){
 *            // 类名/接口名的子类类体
 *      };
 *
 * 匿名内部类的定义位置,以及自身特点和局部内部类类似
 *
 * 匿名内部类对象的使用:
 * 1.不接收,把它的语法当成一个匿名对象去使用
 * 直接"."使用
 *
 * 2.使用语法结构中的"类名/接口名"的引用(父类引用)
 * 接收,然后再使用这个对象
 *
 * 比较一下两种使用方式:
 * 直接使用
 *      优点: 简单,更快捷,可以访问匿名子类中独有的成员
 *      缺点: 一次性,只能用一次
 *
 * 接收再使用:
 *      优点: 不是一次性的了,可以多次使用
 *      缺点: 稍微麻烦一点
 *          不可以访问匿名子类独有成员
 *          且不可强转
 *          因为匿名子类不知道是什么类名
 *
 * @since 10:46
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 创建了A的子类对象,A的子类是匿名的
        System.out.println(new A() {
            // 匿名子类的成员变量
            int num = 666;

            @Override
            void test() {
                System.out.println("匿名内部类A子类对象的实现!");
            }
        }.num);

        new BaseA() {
            @Override
            public void test() {
                System.out.println("抽象类的匿名内部类实现!");
            }
        }.test();

        IA ia = new IA() {
            // 匿名子类的方法体
            // num是匿名子类的成员变量
            int num = 100;
            @Override
            public void test() {
                System.out.println("接口的匿名内部类实现!");
            }
        };
        ia.test();
        // ia.num.sout
    }
}

interface IA {
    void test();
}

abstract class BaseA {
    public abstract void test();
}

class A {
    void test() {
        System.out.println("A");
    }
}
